package net.jcip.examples;

import java.util.*;
import java.util.concurrent.*;

/**
 * QuoteTask
 * <p/>
 * Requesting travel quotes under a time budget
 * @author Brian Goetz and Tim Peierls
 */
public class TimeBudget {
	private static ExecutorService exec = Executors.newCachedThreadPool();

	public List<TravelQuote> getRankedTravelQuotes(TravelInfo travelInfo, Set<TravelCompany> companies,
			Comparator<TravelQuote> ranking, long time, TimeUnit unit) throws InterruptedException {
		List<QuoteTask> tasks = new ArrayList<QuoteTask>();
		for (TravelCompany company : companies)
			tasks.add(new QuoteTask(company, travelInfo));

		// 使用限时 的InvokeAll，将多个任务提交 到一个ExecutorServeice并获得结果
		List<Future<TravelQuote>> futures = exec.invokeAll(tasks, time, unit);

		List<TravelQuote> quotes = new ArrayList<TravelQuote>(tasks.size());
		Iterator<QuoteTask> taskIter = tasks.iterator();
		for (Future<TravelQuote> f : futures) {
			QuoteTask task = taskIter.next();
			try {
				quotes.add(f.get());
			} catch (ExecutionException e) {
				quotes.add(task.getFailureQuote(e.getCause()));
			} catch (CancellationException e) {
				quotes.add(task.getTimeoutQuote(e));
			}
		}

		Collections.sort(quotes, ranking);
		return quotes;
	}

}

// 在预定的时间内请求旅游报价
class QuoteTask implements Callable<TravelQuote> {
	private final TravelCompany company;
	private final TravelInfo travelInfo;

	public QuoteTask(TravelCompany company, TravelInfo travelInfo) {
		this.company = company;
		this.travelInfo = travelInfo;
	}

	TravelQuote getFailureQuote(Throwable t) {
		return null;
	}

	TravelQuote getTimeoutQuote(CancellationException e) {
		return null;
	}

	public TravelQuote call() throws Exception {
		return company.solicitQuote(travelInfo);
	}
}

interface TravelCompany {
	TravelQuote solicitQuote(TravelInfo travelInfo) throws Exception;
}

interface TravelQuote {
}

interface TravelInfo {
}
